package aop02;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;

/**
 * Author:shixiaojun@itany.com
 * Date:2022/5/17 16:02
 * Version:1.0-SNAPSHOT
 * Description:
 */
public class LogInvocationHandler implements InvocationHandler {

    // 定义目标类
    private Object target;

    // 定义有参构造函数,强制性的要求调用者必须传递目标类
    public LogInvocationHandler(Object target) {
        this.target = target;
    }

    /**
     * 交叉业务逻辑
     * @param proxy     代理类,完全没用
     * @param method    目标方法
     * @param args      目标方法的参数列表
     * @return          所代理的目标方法的返回值
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("在"+new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss").format(new Date())+"执行了"+method.getName()+"方法,方法的参数为:"+ Arrays.toString(args));
        // 调用目标方法
        // 返回目标方法的返回值
        // 想要获取到方法返回值,必须知道目标类是谁
        // 但是此处并没有指定目标类是谁
        // 只有在最终获取调用该对象的时候,才会知道当前代理的是哪一个目标类
        // 可以在获取代理类的时候,将目标类传递进来
        // 且由于此处必须要有目标类,因此在调用该对象的时候
        // 强制调用者必须传递当前的目标类
        // 此处可以通过有参构造函数进行传递
        Object result = null;
        try {
            result = method.invoke(target,args);
            System.out.println(method.getName()+"方法执行成功,方法的返回值为:"+result);
        } catch (Exception e) {
            System.out.println(method.getName()+"方法执行遇到了异常,异常信息:"+e);
        } finally{
            System.out.println("后置");
        }
        return result;
    }
}
